#ifndef ShellTView_First
#define ShellTView_First
#ifdef __GNUG__
#pragma interface
#endif

#include "TextView.h"

class PttyConnection;
class Mark;
class OrdCollection;
class Menu;
class GapText;

extern Rectangle gShellTextViewRect;
extern const char *gDefaultArgv[];

//---- ShellTextView -----------------------------------------------------------
//     a TextView connected to a ptty running a shell

class ShellTextView: public TextView {
public:
	MetaDef(ShellTextView);

	ShellTextView(EvtHandler *eh, const Rectangle &r, Text *t, const char *name= 0,
		const char **args= 0, bool becomeconsole= FALSE,
		TextViewFlags= eTextViewDefault, const Point &border= gBorder);

	~ShellTextView();
	virtual const char *GetTermCap();
	virtual const char *GetTerm();

	virtual void BecomeConsole();

	virtual void Received();
	virtual void Submit(const char *buf, int len= -1);
	virtual void SubmitInterrupt(char c);
	void Interrupt();

	virtual bool IsIdle();
	virtual void Reconnect();
	virtual void Start(const char *name= 0, const char **args= 0, bool becomeconsole= FALSE);
	virtual void Done();
	virtual void SlaveDied();
	virtual void CleanupDeath();

	virtual Command *CntrlChar(byte b);
	virtual void DoReveal(bool);
	virtual void RevealOutput(const Rectangle &r, const Point &p);
	void Draw(Rectangle);      // draw output cursor
	Text *SetText(Text*, bool scroll= cRevealTop);  // returns old text
	void SetTtySize(int rows, int cols);
	void SetTtySize(const Rectangle &r, Font *fd);
	void ChangedViewRect(const Rectangle &r);

	const char **GetArgv();
	void ClearOutput();
	void Doit();
	void SetMaxLogSize(int n);
	Command *TtyInput(const char *buf, int len= -1);
		// appends buf to ttys input queue

	//---- overridden to maintain a fence of read only text
	bool DeleteRequest(int from, int to);
	void Paste(Text *insert);

	//---- controller methods
	Command *DoKeyCommand(int, Token);
	static Menu* MakeMenu(int menuId);
	void DoSetupMenu(Menu*);
	Command *DoMenuCommand(int);
	void SelectAll(bool redraw);

	//---- input/output
	OStream& PrintOn(OStream&);
	IStream& ReadFrom(IStream&);

protected:
	void Init(bool doReveal, const char *name, const char **argv, bool cons);
	void Term();
	bool ModifiesReadOnly();
	void Wrap();
	void BackSpace(Text *t, int n);
	void CarriageReturn(Text *t);
	void MarksToEOT();
	void DrawOutputCursor(const Point &p);
	void FlushPendingInput();
	bool HandleSpecialOutChar(char p, GapText*);
	virtual void ProcessOutput(GapText *t, char *buf, int size);
	virtual void InsertReceivedText(Text *t, int from, int to);

protected:
	GapText *noEchoBuffer;  // used when echo is turned off
	int lastSubmit, maxLogSize, state;      // for interpreting ESC-Sequences
	char *pttycstr;
	const char **argv;
	byte *linebuf;
	Mark *outputCursor, *inputCursor;
	OrdCollection *inpQueue;
	bool pendingCR, doReveal, inReceive;

private:
	PttyConnection *ptty;
};

inline const char **ShellTextView::GetArgv()
	{ return argv; }

#endif
